package com.my.swas.sso.module.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.my.swas.common.jwt.JWTToken;
import com.my.swas.common.jwt.JWTUtils;
import com.my.swas.sso.module.admin.entity.Auth;
import com.my.swas.sso.module.admin.entity.Menu;
import com.my.swas.sso.module.admin.entity.User;
import com.my.swas.sso.module.admin.mapper.AuthMapper;
import com.my.swas.sso.module.admin.mapper.MenuMapper;
import com.my.swas.sso.module.admin.mapper.UserMapper;
import com.my.swas.sso.module.admin.service.MenuService;
import com.my.swas.sso.module.admin.vo.ResTreeSelectVo;
import com.my.swas.sso.module.admin.vo.ZTreeMenuVo;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: :MaYong
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
    @Resource
    private MenuMapper menuMapper;

    @Resource
    private AuthMapper roleResourcesMapper;
    
    @Resource
    private UserMapper userMapper;


    @Override
    public List<Menu> loadUserResources(Long userId) {
        User user = userMapper.selectById(userId);
        List<Long> roleIds = Splitter.on(",").splitToList(user.getRoleIds())
                .stream().map(s -> Long.valueOf(s)).collect(Collectors.toList());
        return menuMapper.loadUserResources(roleIds);
    }

    @Override
    public List<ZTreeMenuVo> queryResourcesByRoleId(List<Long> roleIds) {
        List<Menu> menuList = menuMapper.selectList(new QueryWrapper<>());
        QueryWrapper<Auth> roleResourceWrapper = new QueryWrapper();
        roleResourceWrapper.in("role_id", roleIds);
        List<Auth> roleResourcesList = roleResourcesMapper.selectList(roleResourceWrapper);
        if (CollectionUtils.isEmpty(roleResourcesList)) {
            roleResourcesList = Lists.newArrayList();
        }
        List<Long> resIds = roleResourcesList.stream()
                .map(Auth::getMenuId)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(resIds)) {
            resIds = Lists.newArrayList();
        }
        List<ZTreeMenuVo> resTreeVoList = Lists.newArrayList();
        ZTreeMenuVo treeVo = null;
        for (Menu r : menuList) {
            treeVo = new ZTreeMenuVo();
            treeVo.setId(r.getId());
            treeVo.setPId(r.getParentId());
            if (resIds.contains(r.getId())) {
                treeVo.setChecked(true);
            }
            treeVo.setName(r.getName());
            treeVo.setOpen(true);
            resTreeVoList.add(treeVo);
        }
        return resTreeVoList;
    }

    @Override
    public List<ResTreeSelectVo> treeSelectList(Long parentId, Integer type,JWTToken jwtToken) {
        QueryWrapper<Menu> menuQueryWrapper = new QueryWrapper<>();
        if (null != type) {
            menuQueryWrapper.lambda()
                    .eq(Menu::getType, type);
        }
        List<Menu> menuList = this.list(menuQueryWrapper);
        if (null != type) {
            Long userId;
            if(null != jwtToken){
                userId = JWTUtils.getUserId(String.valueOf(jwtToken.getPrincipal()));
            }else{
                userId = JWTUtils.getUserId();
            }
            User user = userMapper.selectById(userId);
            if(null == user){
                return null;
            }
            List<Long> roleIds = Splitter.on(",").splitToList(user.getRoleIds())
                    .stream().map(s -> Long.valueOf(s)).collect(Collectors.toList());

            QueryWrapper<Auth> roleResourceWrapper = new QueryWrapper();
            roleResourceWrapper.lambda().in(Auth::getRoleId, roleIds);
            List<Auth> roleResourcesList = roleResourcesMapper.selectList(roleResourceWrapper);
            List<Long> resLists = roleResourcesList.stream().map(Auth::getMenuId).collect(Collectors.toList());

            menuList = menuList.stream()
                    .filter(menu -> resLists.contains(menu.getId())).collect(Collectors.toList());
        }
        if (null == parentId) {
            parentId = 0l;
        }
        return selectChildren(menuList, parentId);
    }

    /**
     * 递归获取权限树
     *
     * @param menuList
     * @param id
     * @return
     */
    private List<ResTreeSelectVo> selectChildren(List<Menu> menuList, Long id) {
        List<ResTreeSelectVo> resTreeSelectVos = Lists.newArrayList();
        List<Menu> res = menuList.stream()
                .filter(menu -> id.equals(menu.getParentId()))
                .collect(Collectors.toList());
        ResTreeSelectVo resTreeSelectVo = null;
        for (Menu menu : res) {
            resTreeSelectVo = new ResTreeSelectVo();
            resTreeSelectVo.setId(String.valueOf(menu.getId()));
            resTreeSelectVo.setName(menu.getName());
            resTreeSelectVo.setResUrl(menu.getResUrl());
            resTreeSelectVo.setIcon(menu.getIcon());
            resTreeSelectVo.setChildren(selectChildren(menuList, menu.getId()));
            resTreeSelectVo.setClassify(menu.getClassify());
            resTreeSelectVo.setTarget(menu.getTarget());
            if (CollectionUtils.isEmpty(resTreeSelectVo.getChildren())) {
                resTreeSelectVo.setChecked(false);
                resTreeSelectVo.setOpen(true);
            }
            resTreeSelectVo.setMenuUrl(menu.getMenuUrl());
            resTreeSelectVos.add(resTreeSelectVo);
        }
        return resTreeSelectVos;
    }
}
